package top.lilele.adminSystem.service;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import top.lilele.adminSystem.dto.PageDto;
import top.lilele.adminSystem.dto.ProjectListDto;
import top.lilele.adminSystem.entity.AdminLogEntity;
import top.lilele.adminSystem.entity.AdminProjectEntity;
import top.lilele.adminSystem.entity.AdminUserEntity;
import top.lilele.adminSystem.mapper.AdminLogMapper;
import top.lilele.adminSystem.mapper.AdminProjectMapper;
import top.lilele.adminSystem.mapper.AdminUserMapper;
import top.lilele.adminSystem.numEnum.LogEnum;
import top.lilele.adminSystem.numEnum.ProjectStatusEnum;
import top.lilele.adminSystem.utils.Utils;
import top.lilele.adminSystem.vo.LogVo;
import top.lilele.adminSystem.vo.ProjectInfoVo;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @author lilele
 */
@Service
@Slf4j
public class AdminProjectService {

    @Resource
    AdminProjectMapper adminProjectMapper;

    @Resource
    AdminLogService adminLogService;

    @Resource
    AdminLogMapper adminLogMapper;

    @Resource
    AdminProjectHistoryService adminProjectHistoryService;

    @Resource
    AdminUserMapper adminUserMapper;

    /**
     * 添加项目
     *
     * @param adminProjectEntity
     */
    @SneakyThrows
    public void add(AdminProjectEntity adminProjectEntity) {
        String userId = StpUtil.getLoginIdAsString();
        adminProjectMapper.insert(adminProjectEntity);
        AdminUserEntity userInfo = adminUserMapper.selectOne(new LambdaQueryWrapper<AdminUserEntity>().eq(AdminUserEntity::getId, userId));
        String desc = StrUtil.format("{}：创建了项目[{}]", userInfo.getTrueName(), adminProjectEntity.getName());
        adminProjectHistoryService.add(adminProjectEntity.getId(), desc, userId);
//        // 记录日志
//        AdminLogEntity adminLogEntity = new AdminLogEntity();
//        adminLogEntity.setBelongId(adminProjectEntity.getId());
//        adminLogEntity.setContent(new ObjectMapper().writeValueAsString(adminProjectEntity));
//        adminLogService.add(adminLogEntity, StpUtil.getLoginIdAsString(), LogEnum.ADD_PROJECT, null);
    }

    /**
     * 查询项目列表
     *
     * @param projectListDto
     * @return
     */
    public PageDto queryProjectList(ProjectListDto projectListDto) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(StrUtil.isNotEmpty(projectListDto.getType()), "ap.mapId", projectListDto.getType());
        queryWrapper.like(StrUtil.isNotEmpty(projectListDto.getName()), "ap.name", projectListDto.getName());
        queryWrapper.like(StrUtil.isNotEmpty(projectListDto.getNumber()), "ap.number", projectListDto.getNumber());
        queryWrapper.eq(projectListDto.getStatus() != null && !projectListDto.getStatus().equals(ProjectStatusEnum.OVER_TIME.getType()), "ap.status", projectListDto.getStatus());
        queryWrapper.le(projectListDto.getStatus() != null && projectListDto.getStatus().equals(ProjectStatusEnum.OVER_TIME.getType()), "ap.overTime", new Date());
        List<ProjectInfoVo> list = adminProjectMapper.queryProjectList(queryWrapper);
        list.stream().forEach(item -> {
            // 设置逾期
            if (item.getOverTime().getTime() < System.currentTimeMillis()) {
                item.setStatus(ProjectStatusEnum.OVER_TIME.getType());
            }
            item.setStatusLabel(ProjectStatusEnum.getMessageByKeyId(item.getStatus()));
        });
        log.info("list {}", list);
        PageDto pageDto = Utils.generatePage(list, projectListDto.getPageNum(), projectListDto.getPageSize());
        return pageDto;
    }

    /**
     * 查询产品、项目详情
     *
     * @param id
     * @return
     */
    public ProjectInfoVo queryProjectDetail(String id) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("ap.id", id);
        ProjectInfoVo projectInfoVo = adminProjectMapper.queryProjectDetail(queryWrapper);
        return projectInfoVo;
    }

    /**
     * 根据id更新项目信息
     *
     * @param adminProjectEntity
     */
    @SneakyThrows
    public void updateProjectById(AdminProjectEntity adminProjectEntity) {
        // 备份记录
        AdminProjectEntity backInfo = adminProjectMapper.selectById(adminProjectEntity.getId());
        // 更新记录
        adminProjectMapper.updateById(adminProjectEntity);
        // 记录日志
        AdminLogEntity adminLogEntity = new AdminLogEntity();
        adminLogEntity.setBelongId(adminProjectEntity.getId());
        adminLogEntity.setContent(new ObjectMapper().writeValueAsString(adminProjectEntity));
        adminLogService.add(adminLogEntity, StpUtil.getLoginIdAsString(), LogEnum.ADD_PROJECT, backInfo);
    }

    public List<LogVo> queryProjectHistoryList(String id) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("al.belongId", id);
        List<LogVo> list = adminLogMapper.queryLogList(queryWrapper);
        return list;
    }

    public List<Tree<String>> queryProjectListTree() {
        List<AdminProjectEntity> list = adminProjectMapper.selectList(new LambdaQueryWrapper<AdminProjectEntity>().orderByDesc(AdminProjectEntity::getCreatedTime));
        // 构造不包含项目列表数据
        AdminProjectEntity adminProjectEntity = new AdminProjectEntity();
        adminProjectEntity.setId("0");
        adminProjectEntity.setParentId("0");
        adminProjectEntity.setName("其他");
        list.add(adminProjectEntity);
        TreeNodeConfig treeNodeConfig = Utils.generateTreeNode("id", "parentId", "label");
        treeNodeConfig.setWeightKey("createdTime");
        List<Tree<String>> treeNodes = TreeUtil.build(list, "0", treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(treeNode.getId());
                    tree.setName(treeNode.getName());
                    tree.setParentId(treeNode.getParentId());
                });
        return treeNodes;
    }
}
